<?php
/*******************************************************************************

    FinalsClub.org is a platform for students and faculty to collaborate
    and share their knowledge with the world.

    Copyright (C) 2009  Andrew Magliozzi

    This file is a part of FinalsClub.org.

    FinalsClub.org is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    To contact FinalsClub.org, send an email to info@finalsclub.org, or
    send mail to Finals Club, c/o Veritas Tutors, 1132 Massachusetts Avenue,
    Cambridge, MA 02138.

*******************************************************************************/

/**
 * tasks actions.
 *
 * @package    FinalsClub
 * @subpackage tasks
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 12474 2008-10-31 10:41:27Z fabien $
 */
class tasksActions extends sfActions {
	
	public function executeIndex(sfWebRequest $request) {
		$this->task_lists = TaskListPeer::retrieveByGroupId($request->getParameter('group_id'));
		$this->group = GroupPeer::retrieveById($request->getParameter('group_id'));
		
		//crate the calendar data and then add it to the template
		$this->calendar_data = $this->createCalendarData($this->task_lists);
	}

	public function executeNew(sfWebRequest $request) {
		$this->form = new TaskForm(null, array('group_id' => $request->getParameter('group_id')));
		$this->group = GroupPeer::retrieveById($request->getParameter('group_id'));
		$task_list_id = $request->getParameter('task_list_id');
		
		if($task_list_id) {
			$this->form->setDefault('task_list_id', $task_list_id);
			$this->task_list_id = $task_list_id;
		}
		
		if($request->getParameter('isAjax')) {
			$this->setTemplate('subform');
			$this->setLayout(false);
		}
		
	}
	

	public function executeCreate(sfWebRequest $request) {
		$this->forward404Unless($request->isMethod('post'));
		$group_id = $request->getParameter('group_id');
		$this->group = GroupPeer::retrieveById($group_id);
		$this->form = new TaskForm(null, array('group_id' => $group_id));
		
		$task = $request->getParameter($this->form->getName());
		if(isset($task['task_list_id'])) {
			$task_list = TaskListPeer::retrieveByPK($task['task_list_id']);
			$task['creator_id'] = $this->getUser()->getId();
			
			// copy over the task list types
			$task['type_id'] = $task_list->getTypeId();
			$task['type'] = $task_list->getType();
			$task['course_id'] = $task_list->getCourseId();
			$task['resource'] = TaskPeer::$resourceTypes[$task_list->getTypeId()];
			
			//automatically set as open by default
			$task['status'] = TaskPeer::OPEN;
		}
		
		$request->setParameter($this->form->getName(), $task);
		$task = $this->processForm($request, $this->form);
		
	
		if($request->getParameter('isAjax')) {
			$this->setTemplate('item');
			$this->setLayout(false);
			$this->task = $task;
		}
		else
		{
			$this->setTemplate('new');
		}
	}

	public function executeEdit(sfWebRequest $request) {
		$this->forward404Unless($task = TaskPeer::retrieveByPk($request->getParameter('id')), sprintf('Object task does not exist (%s).', $request->getParameter('id')));
		$this->group = $task->getGroup();
		$this->form = new TaskForm($task, array('group_id' => $this->group->getId()));
		if($request->getParameter('isAjax')) {
			$this->setTemplate('subform', 'tasks');
			$this->setLayout(false);
		}
	}
	
	public function executeAssign(sfWebRequest $request) {
		$task = TaskPeer::retrieveById($request->getParameter('id'));
		$this->forward404Unless($task, 'This task does not exist');
		$this->group = $task->getGroup();		
		if($this->getUser()->isGroupAdmin($task->getGroupId()) 
			|| $this->getUser()->isGroupContributor($task->getGroupId())) {
			$task->setUserId($this->getUser()->getId());
			$task->save();
			$this->notifyTaskAssigned($task->getId());
			$this->getUser()->setFlash('success', 'You have successfully accepted this task.');
		} else {
			$this->getUser()->setFlash('error', 'You do not have permission to update this task.');
		}
		$this->setTemplate('item');
		$this->setLayout(false);
		$this->task = $task;
	}

	public function executeUpdate(sfWebRequest $request) {
		$this->forward404Unless($request->isMethod('post') || $request->isMethod('put'));
		$this->forward404Unless($task = TaskPeer::retrieveByPk($request->getParameter('id')), sprintf('Object task does not exist (%s).', $request->getParameter('id')));
		$this->group = $task->getGroup();
		$this->form = new TaskForm($task, array('group_id' => $this->group->getId()));

		$task = $this->processForm($request, $this->form);
		if($request->getParameter('isAjax')) {
			$this->setTemplate('item');
			$this->setLayout(false);
			$this->task = $task;
		}
	}
	
	/**
	 * Ajax request to update tasks
	 * @param $request
	 * @return unknown_type
	 */
	public function executeUpdateStatus(sfWebRequest $request) {
		$task = TaskPeer::retrieveByPK($request->getParameter('id'));
		if($task && $task->getUserId() == $this->getUser()->getId()) {
			$task->setStatus($request->getParameter('status', TaskPeer::OPEN));
			$task->save();
			$this->renderText('updated successfully');
		} else {
			$this->renderText('you do not have permission to update this task');
		}
		return sfView::NONE;
	}

	
	public function executeDelete(sfWebRequest $request) {
		$request->checkCSRFProtection();

		$this->forward404Unless($task = TaskPeer::retrieveByPk($request->getParameter('id')), sprintf('Object task does not exist (%s).', $request->getParameter('id')));
		if($task->getUserId() == $this->getUser()->getId() || $task->getCreatorId() == $this->getUser()->getId()
			|| $this->getUser()->isGroupAdmin($task->getGroupId()) || $this->getUser()->isGroupContributor($task->getGroupId())) {		
			$this->getUser()->setFlash('success', 'You have successfully deleted the task.');
			$task->delete();
		} else {
			$this->getUser()->setFlash('error', 'You do not have permission to delete this task.');
		}

		$this->redirect('tasks/index?group_id='.$task->getGroupId());
	}

	public function executeCalendar(sfWebRequest $request) {
		$this->task_lists = TaskListPeer::retrieveByGroupId($request->getParameter('group_id'));
		$this->group = GroupPeer::retrieveById($request->getParameter('group_id'));
		
		//crate the calendar data and then add it to the template
		$this->calendar_data = $this->createCalendarData($this->task_lists);
	}
	
	protected function processForm(sfWebRequest $request, sfForm $form)
	{
		$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
		if ($form->isValid()) {
			$status = $form->getObject()->isNew() ? 'created' : 'updated';
			$this->getUser()->setFlash('success', 'Your task has been successfully '.$status);
			$task = $form->save();
	
			$this->notifyTaskAssigned($task->getId());

			if($request->getParameter('isAjax')) {
				return $task;
			} else {
				$this->redirect('tasks/index?group_id='.$task->getGroupId());
			}
		}
	}

	/**
	 * function to generate and send email to assigned of task assignment
	 *
	 * @param $taskid - id of task
	 */
	protected function notifyTaskAssigned($taskid) {
		$task = TaskPeer::retrieveByPK($taskid);
		if(!$task) {
			$this->logMessage('Attempt to email task assignation. '.$taskid.' does not exist!', 'crit');	// Log the exception as critical
		  	$this->getUser()->setFlash('warning', 'Attempt to email task assignation. '.$taskid.' does not exist!');	
			return;
		}

		//$group_tasks_url = $this->generateUrl('tasks', array('group_id'=>$task->getGroupId()), true);
		$user = UserPeer::retrieveById($task->getUserId());
		$course = CoursePeer::retrieveById($task->getCourseId());
		$group = GroupPeer::retrieveById($task->getGroupId());

		$smtp_server = sfConfig::get('app_smtp_server');  
		$smtp_user = sfConfig::get('app_smtp_user');
		$smtp_password = sfConfig::get('app_smtp_password');
		try {
		  // Create the mailer
		  $connection = new Swift_Connection_SMTP($smtp_server, 465, Swift_Connection_SMTP::ENC_SSL);
		  $connection->setUsername($smtp_user);
		  $connection->setPassword($smtp_password);
		  $mailer = new Swift($connection);  
		  
		  // Subject line
		  $message = new Swift_Message('Task Assignment');
		 
		  // Render message parts
		 // $mailContext = array('tasks_url'=>$group_tasks_url, 'task'=>$task,'user'=>$user,'group'=>$group,'course'=>$course);	// to be passed as parameters to the partials
		 $mailContext = array('task'=>$task,'username'=>$user->getFullName(),'groupname'=>$group->getName(),'coursename'=>$course->getName(),'taskname'=>$task->getName(),'taskdate'=>$task->getDueDate('m/d/Y'));	
		  $message->attach(new Swift_Message_Part($this->getPartial('notifyHtml', $mailContext), 'text/html'));		// HTML e-mail body
		  $message->attach(new Swift_Message_Part($this->getPartial('notifyPlain', $mailContext), 'text/plain'));	// Plaintext e-mail body
		 
		  // Set the 'To' and 'From' fields
		  $mailer->send($message, $user->getEmail(), $smtp_user);
		  $mailer->disconnect();

		} catch (Exception $e) {
		  	$this->logMessage($e->getMessage(), 'crit');	// Log the exception as critical
		  	$this->getUser()->setFlash('warning', 'Failed to initialize mailer!');		// alert the user e-mailing failed
		}
	}
	
	/**
	 * function to generate task list data in an array format for the calendar partial
	 * @param $request
	 * @return array
	 */
	protected function createCalendarData($task_lists)
	{	
		//generate an associative array with the keys being the next 14 days
	 	$data = array();
	 
		//scan through array and add any days in the next 14 that do not have a key
	 	$current_time = time();
	 	for($i=0; $i < 14; $i++)
	 	{
	 		
	 		$seconds = $i * 60 * 60 * 24;
	 		$day = date('d', $current_time + $seconds);
	 		
	 		$data[$day] = array();
	 		
	 	}

	 	//for each tasklists retrieve each tasks
	 	foreach($task_lists as $task_list){
	 	
	 		$tasks = TaskPeer::retrieveByTaskListId($task_list->getId());
	 		
	 		//for each tasks place it into the correct spot in the array
	 		foreach($tasks as $task)
	 		{
	 			//take the day number of the due date of this task
	 			$day = $task->getDueDate('d');
	 			
	 			//place task data into array with the day as the key
	 			if(isset($data[$day]))
	 			{
	 				$data[$day][] = $task;
	 			}
	 		}
	 	}
	 	
	 	//crop the array into two sections of 7 days
	 	$result[] = array_slice($data,0,7,true);
	 	$result[] = array_slice($data,7,7,true);
	 	
	 	//return array
		return $result;
		
		
	}
}
